package com.iwdnb.gkgz.ui.autoconfigure;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

import javax.sql.DataSource;

import com.alibaba.druid.pool.DruidDataSource;

import com.google.common.collect.Lists;
import com.iwdnb.bmnf.common.excel.core.ExcelService;
import com.iwdnb.bmnf.common.thread.TtlThreadPoolTaskExecutor;
import com.iwdnb.bmnf.common.thread.property.ThreadPoolProperty;
import com.iwdnb.gkgz.application.utils.RedGreenLightUtils;
import com.iwdnb.gkgz.infrastructure.dao.repo.StockDayDataRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * @Author: binchuan.wbc
 * @Date: 2023/01/01
 */
@Configuration
@Slf4j
@ComponentScan(basePackages = {"com.iwdnb.gkgz"})
public class AppAutoConfiguration {

    @Bean
    public RedGreenLightUtils redGreenLightUtils(StockDayDataRepository stockDayDataRepository) {
        return new RedGreenLightUtils(stockDayDataRepository);
    }

    @Bean
    public Executor executor(ThreadPoolProperty threadPoolProperty) {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //核心线程池大小
        executor.setCorePoolSize(threadPoolProperty.getCorePoolSize());
        //最大线程数
        executor.setMaxPoolSize(threadPoolProperty.getMaxPoolSize());
        //队列容量
        executor.setQueueCapacity(threadPoolProperty.getQueueCapacity());
        //活跃时间
        executor.setKeepAliveSeconds(threadPoolProperty.getKeepAliveSeconds());
        //线程名字前缀
        executor.setThreadNamePrefix("stockExecutor-");

        // setRejectedExecutionHandler：当pool已经达到max size的时候，如何处理新任务
        // CallerRunsPolicy：不在新线程中执行任务，而是由调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }

    @Bean
    public ExcelService excelService() {
        return new ExcelService();
    }




    @Bean(initMethod = "init", destroyMethod = "close", name = "quartzDataSource")
    public DataSource dataSource(
        @Value("${spring.quartz.datasource.driverClassName}") String driverClassName,
        @Value("${spring.quartz.datasource.url}") String url,
        @Value("${spring.quartz.datasource.username}") String userName,
        @Value("${spring.quartz.datasource.password}") String password) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setConnectionInitSqls(Lists.newArrayList("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"));
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(userName);
        dataSource.setPassword(password);
        dataSource.setMaxWait(12000L);
        dataSource.setMaxActive(28);
        dataSource.setInitialSize(2);
        dataSource.setMinIdle(1);
        dataSource.setTimeBetweenEvictionRunsMillis(30000);
        dataSource.setTestOnBorrow(false);
        dataSource.setTestWhileIdle(true);
        dataSource.setValidationQuery("select 1");
        return dataSource;
    }
}
